/*!
 * file : um.js
 * gitee :
 * github :
 * author : 袁泉/Data.
 * version : v1.0.3
 * create time : 2018年6月16日23:24:15
 * update time : 2018年6月18日14:37:54=
 */

;!(function ($, win, undefined) {
    var umUI = {
        version: '1.0.2',
        debug: true,
        uiInslist: {},
        defaults: {
            id: '',
            type: 'panel',
            renderTo: 'body',
            items: []
        },
        layForm: {},
        layDate: {},
        layElement: {},
        uiTemplates: {
            panel: {
                template: '',
                x: 0,
                y: 0,
                width: 0,
                height: 0,
                bodyPadding: 0,
                cls: '',
                style: ''
            },
            form: {
                template: '<form data-id="%id" id="%id" class="abs u-panle form layui-form layui-form-pane %cls" style="top:%ypx;left:%xpx;width:%widthpx;height: %heightpx;%style" action=""><button class="layui-btn" id="%idSubmitBt" lay-submit lay-filter="%id" style="display: none">立即提交</button> <button type="reset" id="%idRestBt" style="display: none" class="layui-btn layui-btn-primary">重置</button></form>',
                x: 0,
                y: 0,
                width: 0,
                height: 0,
                cls: '',
                style: '',
                event: {},
                dynamicAttr: function () {

                }
            },
            //文本输入框
            textbox: {
                template: '<div data-id="%id" id="%id" style="z-index:%zIndex;height:%heightpx;width:%widthpx;top:%ypx;left:%xpx; %style" class="abs widgetItem form-inline %cls" >\n' +
                '                <label class="layui-form-label %idLable" style="padding-top:0px;line-height:%heightpx;height:%heightpx;width:%labelWidthpx;color:%labelColor">%fieldLabel</label>\n' +
                '                <div class="layui-input-inline">\n' +
                '                    <input style="height:%heightpx;width:%contentWidthpx" %readonly %disabled tabindex="%tabIndex" name="%name" placeholder="%emptyText" value="%value" lay-verify="%verify" autocomplete="off" class="%idInput layui-input"\n' +
                '                           type="%inputType">\n' +
                '                </div>\n' +
                '            </div>',
                id: "",//
                name: "",//
                height: 50,
                width: 200,
                fieldLabel: "未命名",//
                labelWidth: 50,//
                labelColor: '#000000',
                contentWidth: 50,
                x: 0,//
                y: 0,//
                tabIndex: 1,
                zIndex: 1001,
                value: "",//
                cls: "",
                style: "",
                inputType: "text",
                emptyText: "请输入...",//
                readonly: false,
                disabled: false,
                verify: '',
                event: {},
                dynamicAttr: function () {
                    this.contentWidth = this.width - this.labelWidth;
                    umUI.debug && console.log('计算出contentWidth:', this.contentWidth);
                    this.readonly = this.readonly ? 'readonly' : '';
                    this.disabled = this.disabled ? 'disabled' : '';
                }
            },
            hidden: {
                template: '<input type="hidden" name="%name" value="%value">',
                id: "",//
                name: "",//
                value: "",//
                dynamicAttr: function () {
                }
            },
            span: {
                template: '<span id="%id" data-id="%id" style="text-align: %textAlign;%VAlign;z-index:%zIndex;height:%heightpx;width:%widthpx;top:%ypx;left:%xpx;color:%color;%style" class="%id abs widgetItem %cls">%value</span>',
                id: "",//
                height: 50,//
                width: 200,//
                color: '#000000',//字体颜色
                x: 0,//
                y: 0,//
                zIndex: 1001,//层级
                value: "",//默认值
                cls: "layui-badge-rim",//class
                style: "",//样式
                event: {},//事件
                textAlign: 'center',//文字对齐方式
                VAlign: true,//垂直居中
                dynamicAttr: function () {
                    var vAlign = '';
                    if (this.VAlign) {
                        vAlign = 'line-height:' + this.height + 'px';
                    }
                    this.VAlign = vAlign;
                }
            },
            //下拉框
            dropdownlist: {//下拉列表
                template: '<div data-id="%id" style="z-index:%zIndex;height:%heightpx;width:%widthpx;top:%ypx;left:%xpx; %style" id="%id" class="abs widgetItem layui-form-item %cls">\n' +
                '      <label class="layui-form-label %idLable" style="padding-top:0px;line-height:%heightpx;height:%heightpx;width:%labelWidthpx;color:%labelColor">%fieldLabel</label>\n' +
                '      <div class="layui-input-inline" style="height:%heightpx;width:%contentWidthpx">\n' +
                '<select %disabled style="height:%heightpx;width:%contentWidthpx" tabindex="%tabIndex" value="%value" lay-verify="%verify" class="%idSelect" name="%name" >\n' +
                /* '<option value="">%emptyText</option>' +*/
                '%data' +
                '      </select>' +
                '      </div>\n' +
                '    </div>',
                templateChild: '<option value="%value" %selected >%name</option>',
                id: "",//
                name: "",//
                height: 50,//
                width: 200,//
                fieldLabel: "未命名",//
                labelWidth: 50,//
                labelColor: '#000000',//
                contentWidth: 50,//
                emptyText: '请选择',
                x: 0,//
                y: 0,//
                tabIndex: 1,//
                zIndex: 1001,//
                value: "",//
                cls: "",//
                style: "",//
                disabled: '',//disabled
                verify: '',//
                data: null,//[{name: '请选择', value: '1', selected: 'selected'}]
                position: 'absolute',//定位方式
                loadData: function (data) {
                    var widget = $('#' + this.id);
                    var select = widget.find('select');
                    select.html('');
                    this.data = data;
                    var opHtml = this.renderData();
                    select.html(opHtml);
                    umUI.layForm.render();
                },
                dynamicAttr: function () {
                    this.contentWidth = this.width - this.labelWidth;
                    umUI.debug && console.log('计算出contentWidth:', this.contentWidth);
                },
                renderData: function () {
                    var that = this;
                    var childHtml = '';
                    $.each(that.data, function (childIndex, childVal) {
                        var childHtmlTemplate = that.templateChild;
                        $.each(childVal, function (key, val) {
                            childHtmlTemplate = Utils.reple(childHtmlTemplate, '%' + key, val);
                        });
                        childHtml += childHtmlTemplate;
                    });
                    return childHtml;
                },
                event: {}


            },
            //日期选择框
            datepicker: {
                template: ' <div class="layui-form-item widgetItem abs %cls " id="%id" data-id="%id"  style="z-index:%zIndex;top:%ypx;left:%xpx;width:%widthpx;height: %heightpx;%style">\n' +
                '    <label class="layui-form-label %idLabel" style="padding-top:0px;line-height:%heightpx;height:%heightpx;width:%labelWidthpx;color:%labelColor">%fieldLabel</label>\n' +
                '    <div class="layui-input-inline" style="height:%heightpx;width:%contentWidthpx">\n' +//
                '      <input name="%name"  id="%idInput" type="text" %disabled %readonly style="height:%heightpx;width:%contentWidthpx" tabindex="%tabIndex" value="%value" placeholder="%emptyText" lay-verify="%verify"  lay-verify="%verify"  autocomplete="off" class="layui-input %idInput">\n' +
                '    </div>\n' +
                '  </div>',
                id: "",//
                name: "",//
                height: 50,//
                width: 200,//
                fieldLabel: "未命名",//
                labelWidth: 50,//label宽度
                labelColor: '#000000',//label颜色
                contentWidth: 50,//内容宽度（不需要传，自动计算）
                x: 0,//y
                y: 0,//x
                tabIndex: 1,//TabIndex
                zIndex: 1001,//层级（在最上级的DIv上）
                value: "",//默认值
                cls: "",//样式（在最上层的Div上）
                style: "",//样式(在最上层的Div上)
                emptyText: "yyyy-MM-dd",//为空时提示
                readonly: false,//'readonly',//只读
                disabled: false,//'disabled',//禁止
                verify: '',//
                range: false,//是否时间区域
                format: 'yyyy-MM-dd',//时间格式
                dateType: 'date',//时间类型
                /* year	年选择器	只提供年列表选择
                 month	年月选择器	只提供年、月选择
                 date	日期选择器	可选择：年、月、日。type默认值，一般可不填
                 time	时间选择器	只提供时、分、秒选择
                 datetime	日期时间选择器	可选择：年、月、日、时、分、秒*/
                isNowDate: false,//是否当前时间
                isInitValue: true,////是否允许填充初始值，默认为 true
                maxValue: '',
                minValue: '',
                showBottom: true,//是否显示底部栏
                showTodayButton: true,//是否显示今天按钮
                showClearButton: true,//是否显示清空按钮
                showConfirmButton: true,//是否显示确定按钮
                theme: 'grid',//主题：可以为molv、grid 或者颜色值
                calendar: true,//是否显示节日
                mark: '0-0-1:One',//标注重要日子(日期:名称;日期:名称;日期:名称)0 即代表每一年,0-0 即代表每年每月
                event: {
                    ready: function (date) {
                    },//控件初始打开的回调
                    change: function (value, date, endDate) {
                    },//日期时间被切换后的回调
                    done: function () {
                    },
                },
                dynamicAttr: function () {
                    this.contentWidth = this.width - this.labelWidth;
                    umUI.debug && console.log('计算出contentWidth:', this.contentWidth);
                    this.readonly = this.readonly ? 'readonly' : '';
                    this.disabled = this.disabled ? 'disabled' : '';

                },//控件选择完毕后的回调
                render: function (layDate) {//渲染
                    var renderParam = {
                        elem: '#' + this.id + 'Input'
                        , range: this.range
                        , type: this.dateType
                        , format: this.format
                        , value: this.isNowDate ? new Date() : this.value
                        , isInitValue: this.isInitValue
                        , theme: this.theme
                        , calendar: this.calendar
                        , ready: this.event.ready//控件初始打开的回调
                        , change: this.event.change//日期时间被切换后的回调
                        , done: this.event.done,//控件选择完毕后的回调
                    }

                    if (this.minValue) {
                        var min = parseInt(this.minValue);
                        if (isNaN(min)) {
                            min = this.minValue;
                        }
                        renderParam.min = min;
                    }
                    if (this.maxValue) {
                        var max = parseInt(this.maxValue);
                        if (isNaN(max)) {
                            max = this.maxValue;
                        }
                        renderParam.max = max;
                    }
                    var btns = [/*'clear', 'now','confirm'*/]
                    this.showClearButton && (btns.push('clear'));
                    this.showTodayButton && (btns.push('now'));
                    this.showConfirmButton && (btns.push('confirm'));
                    renderParam.btns = btns;
                    if (this.mark) {
                        var marks = {};
                        var items = this.mark.split(';')
                        $.each(items, function (i, v) {
                            var arr = v.split(':');
                            marks[arr[0]] = arr[1];
                        })
                        renderParam.mark = marks;
                    }
                    console.log('laydata:', renderParam)
                    layDate.render(renderParam)
                }
            },
            //折叠面板
            grouppanel: {
                template: '<div id="%id" data-id="%id" style="z-index:%zIndex;top:%ypx;left:%xpx;width:%widthpx;height: %heightpx;%style" class="%id layui-collapse widgetItem abs %cls">' +
                '</div>',
                id: "",//
                name: "",//
                height: 500,
                width: 300,
                x: 0,//
                y: 0,//
                zIndex: 1001,
                cls: "",
                style: "",
                event: {},//事件
                dynamicAttr: function () {
                },//动态属性
                render: function (layElement) {

                }
            },
            grouppanelTab: {
                template: '  <div id="%idPanle" data-id="%id" style="position: relative;z-index: %zIndex;%style" class="widgetItem noDrag noSize %id layui-colla-item %cls">\n' +
                '    <h2 class="layui-colla-title" style="height: %tabHeightpx;line-height:%tabHeightpx; ">%title</h2>\n' +
                '    <div class="layui-colla-content %layuiShow " style="padding:0px;height: %heightpx"">' +
                '       <div id="%id" style="width: 100%;height: %heightpx" class="abs u-panle"></div>' +
                '   </div>\n' +
                '  </div>',
                title: '未命名',
                id: '',
                layuiShow: true,//'layui-show',//默认展开
                cls: '',
                style: '',
                zIndex: 1001,
                tabHeight: 35,
                height: 300,
                event: {},//事件
                dynamicAttr: function () {
                    if (this.layuiShow) {
                        this.layuiShow = 'layui-show';
                    } else {
                        this.layuiShow = '';
                    }
                }
            },
            tabstrip: {
                template: '<div %closable  lay-filter="%id" class="abs layui-tab %cls widgetItem" id="%id" data-id="%id" style="z-index:%zIndex;top:%ypx;left:%xpx;width:%widthpx;height: %heightpx;%style" >\n' +
                '  <ul id="%id_title" style="background: %titleBgColor;" class="%idTitle layui-tab-title">\n' +

                '  </ul>\n' +
                '  <div id="%id_content" style="padding: 0px;" class="  %idContent layui-tab-content ">\n' +

                '  </div>\n' +
                '</div>',
                id: "",//
                name: "",//
                height: 500,
                width: 300,
                titleBgColor: '#fff',//头部背景颜色
                x: 0,//
                y: 0,//
                zIndex: 1001,
                cls: "",
                style: "",
                closable: false,
                event: {},//事件
                dynamicAttr: function () {
                    if (this.closable) {
                        this.closable = 'lay-allowClose="true"';
                    } else {
                        this.closable = '';
                    }
                },
                render: function () {
                    umUI.layElement.render();
                }
            },
            tab: {
                template: {
                    title: '<li class="%layuiThis" lay-id="%id">%title</li>',
                    content: '<div class="layui-tab-item %layuiShow widgetItem noDrag noSize" style="width: 100%;height: %heightpx" data-id="%id"><div style="width: 100%;height: %heightpx" class="u-panle abs"  id="%id"></div></div>'
                },
                title: '未命名',
                cls: '',
                layuiShow: '',//'layui-show'
                layuiThis: '',//'layui-this'
                event: {},//事件
                dynamicAttr: function () {
                    //layShow
                    if (this.layuiShow) {
                        this.layuiShow = 'layui-show';
                        this.layuiThis = 'layui-this';
                    } else {
                        this.layuiShow = '';
                        this.layuiThis = '';
                    }
                },
                render: function () {
                    umUI.layElement.render();
                }
            }
        },
        ui: function (uiData) {
            umUI.uiCtrl.renderUis([uiData]);
            umUI.layForm && umUI.layForm.render();
        },
        uiCtrl: {
            /***
             * 递归渲染每一个控件
             * @param uis 控件的items
             * @param renderTo 渲染到哪个容器内（递归传递为：上级容器的id）
             */
            renderUis: function (uis, renderTo) {
                $.each(uis, function (i, v) {
                    console.log(v.type)
                    if (!v.renderTo) {
                        v.renderTo = renderTo;
                    }
                    var id = umUI.uiCtrl.renderUi(v, v.renderTo);
                    if (v['items']) {
                        if (typeof id == 'string') {
                            umUI.uiCtrl.renderUis(v['items'], '#' + id);
                        } else {
                            umUI.debug && console.error('renderUi返回的id不是一个字符串，请检查！id:', id);
                        }
                    }
                });
            },
            /***
             * 渲染一个控件
             * @param uiData 控件对象
             * @param xRenderTo 渲染到哪个容器内（#xxx/.xxx/document.getElementById('')）
             * @param isReturnStr 是否不渲染到容器内，而是直接返回html模板
             * @returns {*}
             */
            renderUi: function (uiData, xRenderTo, isReturnStr) {

                umUI.debug && console.log('渲染一个控件', uiData.type, xRenderTo);
                var uiTemp = umUI.uiTemplates[uiData.type];
                if (!uiTemp) {
                    return null;
                }
                uiData = $.extend(true, {}, uiTemp, uiData);
                uiData.dynamicAttr && uiData.dynamicAttr();//调用本身的动态属性生成方法
                if (!uiData['id']) {
                    uiData['id'] = 'widget' + Utils.randomStr(5);
                }
                var htmlTemplate = uiData.template;
                //如果只有一个模板
                if (typeof  htmlTemplate == 'string') {
                    htmlTemplate = umUI.uiCtrl.renderTemplate(uiData, htmlTemplate);
                    if (!isReturnStr) {
                        var widget = $(htmlTemplate);
                        //存放该UI的一个容器
                        var uiWarp;
                        var renderTo = $(xRenderTo);
                        if (!renderTo[0]) {
                            uiWarp = $('body');
                        } else {
                            uiWarp = renderTo;
                        }
                        uiWarp.append(widget);
                        umUI.uiInslist[uiData.id] = uiData;
                        umUI.uiCtrl.layRender(uiData);
                        return uiData.id;
                    }
                } else {//有多个模板（约定：模板对象的键必须为上级容器中   id_‘‘key’’ ）
                    $.each(htmlTemplate, function (key, val) {
                        htmlTemplate[key] = umUI.uiCtrl.renderTemplate(uiData, val);
                        if (!isReturnStr) {
                            var widget = $(htmlTemplate[key]);
                            //存放该UI的一个容器
                            var uiWarp;
                            var renderTo = $(xRenderTo + '_' + key);
                            if (!renderTo[0]) {
                                uiWarp = $('body');
                            } else {
                                uiWarp = renderTo;
                            }
                            uiWarp.append(widget);
                        }
                    });
                    umUI.uiInslist[uiData.id] = uiData;
                    umUI.uiCtrl.layRender(uiData);
                    return uiData.id;
                }
                return htmlTemplate;

            },
            /***
             * 渲染模板
             * @param uiData
             * @param template
             * @returns {*}
             */
            renderTemplate: function (uiData, template) {
                var htmlTemplate = template;
                $.each(uiData, function (i, v) {//填充属性(i:属性名称，v:属性值)
                    //填充Data
                    if (i == 'data') {
                        umUI.debug && console.log('发现这个控件有Data:', v);
                        if (!uiData.templateChild) {
                            umUI.debug && console.error(uiData.type + '控件存在data属性，但是没有templateChild！请检查控件是否维护错误！');
                            v = '';
                        } else if (uiData.templateChild) {
                            v = uiData.renderData();
                        }
                    }
                    htmlTemplate = Utils.reple(htmlTemplate, '%' + i, v !== undefined ? v : '');
                });
                return htmlTemplate;
            },
            /***
             * 调用控件对象中的render方法渲染控件
             * @param uiItemData
             */
            layRender: function (uiItemData) {
                uiItemData.render && uiItemData.render(umUI.layDate);
            },

        },
        init: function (layForm, layDate, layElement) {
            this.layForm = layForm;
            this.layDate = layDate;
            this.layElement = layElement;
        }
    };
    var Utils = {
        //替换
        reple: function (str, key, val) {
            //正则实现:
            if (str && typeof str == 'string') {
                var regExp = new RegExp(key, "g");
                return str.replace(regExp, val);
            } else {
                umUI.debug && console.error('替换方法出现异常替换:', str, typeof str);
            }
            return str;
            //递归实现：
            /* if (str.indexOf(key) > -1) {
                 return Utils.reple(str.replace(key, val), key, val);
             } else {
                 return str;
             }*/
        },
        //随机字符
        randomStr: function (len) {
            len = len || 32;
            var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz';
            /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
            var maxPos = $chars.length;
            var str = '';
            for (var i = 0; i < len; i++) {
                str += $chars.charAt(Math.floor(Math.random() * maxPos));
            }
            return str;
        },
        isDom: function (obj) {
            return !!(obj && typeof window !== 'undefined' && (obj === window || obj.nodeType));
        },
        isJson: function (obj) {
            var isjson = (typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length);
            return isjson;
        },
        getNodeByClassName: function (node, className, parentWindow) {
            parentWindow = parentWindow || win;
            var that = this;
            if (node === parentWindow.document.body) {
                return null;
            }
            var cls = node.classList;
            if (cls.contains(className)) {
                return node;
            } else {
                return that.getNodeByClassName(node.parentNode, className);
            }
        },
        newGuid: function () {
            var guid = "";
            for (var i = 1; i <= 32; i++) {
                var n = Math.floor(Math.random() * 16.0).toString(16);
                guid += n;
                if ((i == 8) || (i == 12) || (i == 16) || (i == 20))
                    guid += "-";
            }
            return guid;
        },
        array_remove_repeat: function (a) {
            var r = [];
            for (var i = 0; i < a.length; i++) {
                var flag = true;
                var temp = a[i];
                for (var j = 0; j < r.length; j++) {
                    if (temp === r[j]) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    r.push(temp);
                }
            }
            return r;
        },
        array_difference: function (a, b) {
            var that = this;
            var clone = a.slice(0);
            for (var i = 0; i < b.length; i++) {
                var temp = b[i];
                for (var j = 0; j < clone.length; j++) {
                    if (temp === clone[j]) {
                        clone.splice(j, 1);
                    }
                }
            }
            return that.array_remove_repeat(clone);
        },
        getParams: function (data) {
            var arr = [];
            for (var param in data) {
                arr.push(encodeURIComponent(param) + '=' + encodeURIComponent(data[param]));
            }
            arr.push(('v=' + Math.random()).replace('.'));
            return arr.join('&');
        },
        ajax: function (options) {
            // eq
            /*Utils.ajax({
                url: url ? url : grid.url,
                type: grid.type,
                data: grid.params,
                async: true,
                dataType: grid.dataType,
                before: function () {
                    that.loadTip(id);
                },
                success: function (text, xml) {
                    var data = JSON.parse(text);
                    setTimeout(function () {
                        that.createBodyContent(id, data);
                        that.closeLoadTip(id);
                    }, 0);
                },
                error: function (status) {
                    that.closeLoadTip(id);
                },
                complete: function () {
                }
            });*/
            var that = this;
            options = options || {};
            options.type = (options.type || "GET").toUpperCase();
            options.dataType = options.dataType || 'json';
            options.async = options.async || true;
            var params = that.getParams(options.data);
            var xhr;
            if (window.XMLHttpRequest) {
                xhr = new XMLHttpRequest();
            } else {
                xhr = new ActiveXObject('Microsoft.XMLHTTP')
            }
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    var status = xhr.status;
                    if (status >= 200 && status < 300) {
                        options.success && options.success(xhr.responseText, xhr.responseXML);
                    } else {
                        options.error && options.error(status);
                    }
                    options.complete && options.complete();
                }
            };
            if (options.type == 'GET') {
                options.before && options.before();
                xhr.open("GET", options.url + (options.url.indexOf("?") > -1 ? "&" : '?') + params, options.async);
                xhr.send(null)
            } else if (options.type == 'POST') {
                options.before && options.before();
                xhr.open('POST', options.url, options.async);
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                xhr.send(params);
            }
        }
    };
    win.um = {
        init: function (layForm, layDate, layElement) {
            return umUI.init(layForm, layDate, layElement);
        },
        ui: function (param) {
            if (typeof  param == 'string') {
                return this.getUiById(param);
            } else {
                return umUI.ui(param);
            }
        },
        getUiById: function (id) {
            return umUI.uiInslist[id];
        }
    };
})(jQuery, window);
